_$.Component = function(target){
    var _this = this;
    target = _$.getTarget(target);
    _this.events={};
    _this.el = target;
    _this.uid = uuid();
    _this.id = target.attr("id");

    var opts = _this._attrOpts();
    var properties = _this._attrProps();
    _this.options = $.extend(true,opts,_$.parser.parseOptions(target,properties));

    _$.reg(_this);
    _this._create();
};

_$.Component.prototype = {
    isComponent : true,
    id:"",
    uid:"",
    component:null,
    _cls:_$._clsPre + "component",
    _uiCls:_$._uiPreCls + "component",
    _create:function(){},
        _attrProps:function(){
        return ['id', 'remark'];
    },
    _attrOpts:function(){},
    _setStyle:function(){},
    _getEvents:function(keys){
        var _this = this;
        $.map(keys, function(p){
            var func = _this.getOption(p);
            if(isNotEmpty(func)){
                func = _$.getFunctoin(func);
                _this._on(p,func);
            }
        });
    },
    _loadSuccess:function(){
        var _this=this;
        _$.parser.onComponentComplete.call(_$.parser,_this.id,_this.type);
    },
    _bindEvents:function(){},
    _fire : function(type, e) {
        var _this = this;

        type = type.toLowerCase();
        var event = _this.events[type];
        if (event) {
            if (!e) {
                e = {};
            }
            if (e && e != _this) {
                e.source = _this;
                if (!e.type) {
                    e.type = type;
                }
            }
            for ( var c = 0, a = event.length; c < a; c++) {
                var item = event[c];
                if (item) {
                    item[0].apply(item[1], [ e ]);
                }
            }
        }
    },
    _on : function(type, fn, scope) {
        var _this = this;
        if (typeof fn == "string") {
            var func = _$.getFunctoin(fn,scope);
            if (func) {
                fn = func;
            }
        }
        if (typeof fn != "function" || !type) {
            return false;
        }
        type = type.toLowerCase();
        var event = _this.events[type];
        if (!event) {
            event = _this.events[type] = [];
        }
        scope = scope || _this;
        if (!_this._findListener(type, fn, scope)) {
            event.push([ fn, scope ]);
        }
        return _this;
    },
    _un : function(type, fn, scope) {
        var _this = this;
        if (typeof fn != "function") {
            return false;
        }
        type = type.toLowerCase();
        var event = _this.events[type];
        if (event) {
            scope = scope || _this;
            var item = _this._findListener(type, fn, scope);
            if (item) {
                event.remove(item);
            }
        }
        return _this;
    },
    _findListener : function(type, func, scope) {
        var _this = this;
        type = type.toLowerCase();
        scope = scope || _this;
        var event = _this.events[type];
        if (event) {
            for ( var i = 0; i < event.length ; i++) {
                var item = event[i];
                if (item[0] === func && item[1] === scope) {
                    return item;
                }
            }
        }
    },
    _replaceNode:function(source){
        var _this = this;
        var template = Handlebars.compile(source);
        var result = template(_this.options);
        var element = $(result);
        _this.el.replaceWith(element);
        _this.el = element;
        _this.el.attr("componentId",_this.uid);
    },
    setOption:function(key,value){
        var _this = this;
        _this.options[key]=value;
    },
    getOption:function(key){
        var _this = this;
        var value = _this.options[key];
        return value;
    },
    toString:function(){
        var _this = this;
        return _this.id;
    },
    destroy : function() {
        var _this = this;
        this.el.remove();
        _$.unReg(_this);
    }
};